/**
 * 企业管理
 */
package ms.core.gateway.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ms.core.common.*;
import ms.core.common.consts.SysErr;
import ms.core.common.utils.RequestUtils;
import ms.core.common.utils.UploadedFileUtils.FileDoc;
import ms.core.gateway.bean.*;
import ms.core.gateway.dao.*;
import ms.core.gateway.request.CreateCorpRequest;
import ms.core.gateway.request.QueryCorpRequest;
import ms.core.gateway.request.UpdateCorpRequest;
import ms.core.gateway.response.SysCorpVO;
import ms.core.gateway.system.Application;
import ms.core.gateway.tool.SessionTool;
import ms.core.tool.JsonTool;
import ms.core.tool.StrTool;
import ms.core.tool.SysTool;

public class SysCorpUtils {
	private SysCorpDao dao;

	public SysCorpUtils(){ 
		dao = new SysCorpDao();
	}

	public void newDocType(String corpUid, String docType) {
		SysCorpBean exist = dao.getCorp(corpUid, SysCorpBean.class);
		if (exist==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");
		
		List<String> docTypes = JsonTool.jsonToListBean(exist.getDocType(), String.class);
		if (docTypes==null) docTypes = new ArrayList<>();
		if (docTypes.contains(docType))
			throw new AppException(SysErr.SYS_DATA_EXISTS, "此资料分类已存在.");
		
		docTypes.add(docType);
		dao.updateCorpDocType(exist.getId(), docTypes, null);
	}

	public void edtDocType(String corpUid, String oldDocType, String newDocType) {
		SysCorpBean exist = dao.getCorp(corpUid, SysCorpBean.class);
		if (exist==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");
		
		List<String> docTypes = JsonTool.jsonToListBean(exist.getDocType(), String.class);
		if (docTypes==null) docTypes = new ArrayList<>();
		if (!docTypes.contains(oldDocType) || docTypes.contains(newDocType))
			throw new AppException(SysErr.SYS_DATA_EXISTS, "旧资料分类不存在或新资料分类已存在.");

		int idx = docTypes.indexOf(oldDocType);
		docTypes.set(idx, newDocType);
		// 需要更新已有分类资料
		List<FileDoc> files = JsonTool.jsonToListBean(exist.getDocs(), FileDoc.class);
		if (files!=null && files.size()>0) {
			for(FileDoc file: files) {
				if (oldDocType.equals(file.getCatalog())) {
					file.setCatalog(newDocType);
				}
			}
		}
		dao.updateCorpDocType(exist.getId(), docTypes, files);
	}

	/**
	 * 删除企业资料分类
	 * 
	 * @param corpUid
	 * @param docType
	 */
	public void delDocType(String corpUid, String docType) {
		SysCorpBean exist = dao.getCorp(corpUid, SysCorpBean.class);
		if (exist==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");
		
		List<String> docTypes = JsonTool.jsonToListBean(exist.getDocType(), String.class);
		if (docTypes==null) docTypes = new ArrayList<>();
		if (!docTypes.contains(docType))
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "资料分类不存在.");

		// 删除文件分类
		docTypes.remove(docType);
		// 需要删除已有分类资料
		List<FileDoc> files = JsonTool.jsonToListBean(exist.getDocs(), FileDoc.class);
		if (files!=null && files.size()>0) {
			int i=0;
			while(i<files.size()) {
				if (docType.equals(files.get(i).getCatalog())) {
					SysTool.deleteFile(Application.DIR_CORP_DOC.getDisk()+"/"+files.get(i).getFile());
					files.remove(i);
				} else {
					i++;
				}
			}
		}

		dao.updateCorpDocType(exist.getId(), docTypes, files);
	}

	/**
	 * 更新企业信息
	 * @param corp
	 * @return
	 */
	public void updateCorp(UpdateCorpRequest corp) {
		if (Application.userDelegate!=null) Application.userDelegate.beforeUpdateCorp(corp);

		SysCorpBean exist = dao.getCorp(corp.getUid(), SysCorpBean.class);
		if (exist==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");

		dao.updateCorp(exist.getId(), corp);

		// 涉及更改企业类型，需刷新用户类型及权限
		if (exist.getCtype()!=corp.getCtype()) {
			// 更新企业对应在线用户的用户类型
			SessionTool.updateCorpType(corp.getUid(), corp.getCtype());
			// 重新分配角色权限
			SysRoleUtils.createAdminRole(corp.getUid(), corp.getCtype(), true);
		}

		SysCorpVO updateCorp = dao.getCorp(exist.getUid(), SysCorpVO.class);
		if (Application.userDelegate!=null) Application.userDelegate.afterUpdateCorp(updateCorp);		
	}

	/**
	 * 开启/关闭企业信息
	 * @param uid
	 * @param state
	 * @return
	 */
	public void setCorpState(String uid, int state) {
		SysCorpBean corp = dao.getCorp(uid, SysCorpBean.class);
		if (corp==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");

		if ((corp.getCtype() & SysCorpBean.SUPPER_CORP) == SysCorpBean.SUPPER_CORP)
			throw new AppException(SysErr.SYS_ACCESS_FORBID, "不允许对平台企业执行此操作.");

		if (corp.getState()==state)
			return;

		Map<String, Object> values = new HashMap<>();
		values.put("state", state);
		dao.modRecord(corp.getId(), values);

		// 删除该企业下在线用户会话
		if (state==SysCorpBean.STATE_DELETE) SessionTool.invalidCorpSession(uid);
		// 通知应用企业状态变更
		if (Application.userDelegate!=null) Application.userDelegate.afterUpdateCorpState(uid, state);
	}

	/**
	 * 保存上传企业附件资料
	 * 
	 * @param corpUid
	 * @param list
	 */
	public void updateDoc(String corpUid, List<FileDoc> list) {
		SysCorpBean corp = dao.getCorp(corpUid, SysCorpBean.class);
		if (corp==null) {
			RequestUtils.deleteAnnexs(list);
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");
		}
		if (SysTool.dirExists(Application.DIR_CORP_DOC.getDisk(), true)<1) {
			RequestUtils.deleteAnnexs(list);
			throw new AppException(SysErr.SYS_UPLOAD_ERR, "创建文件夹失败.");
		}

		List<FileDoc> files = StrTool.isBlank(corp.getDocs()) ? new ArrayList<>() : JsonTool.jsonToListBean(corp.getDocs(), FileDoc.class);
		// 文件存到正式目录
		for(FileDoc doc: list) {
			// 获取照片上传后的磁盘文件名(无路径)
			String fileName = SysTool.getFileName(doc.getFile());
			File origin = new File(doc.getFile());
			File dest = new File(Application.DIR_CORP_DOC.getDisk()+"/"+fileName);
			origin.renameTo(dest);
			
			// 合并附件
			FileDoc e = new FileDoc();
			e.setCatalog(doc.getCatalog());
			e.setDesc(doc.getDesc());
			e.setFile(fileName);
			e.setName(doc.getName());
			files.add(e);
		}

		dao.updateCorpDoc(corp.getId(), files);
	}


	/**
	 * 修改企业资料分类及附件类型
	 * 
	 * @param corpUid
	 * @param file
	 * @param catalog
	 * @param docType
	 */
	public void editDoc(String corpUid, String file, String catalog, String docType) {
		SysCorpBean corp = dao.getCorp(corpUid, SysCorpBean.class);
		if (corp==null) {
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");
		}

		boolean exist = false;
		List<FileDoc> files = StrTool.isBlank(corp.getDocs()) ? new ArrayList<>() : JsonTool.jsonToListBean(corp.getDocs(), FileDoc.class);
		for(FileDoc item: files) {
			if (file.equals(item.getFile())) {
				item.setCatalog(catalog);
				item.setDesc(docType);
				exist = true;
				break;
			}
		}
		if (!exist)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "企业无此附件.");

		dao.updateCorpDoc(corp.getId(), files);
	}
	
	private void deleteFile(String fileName, List<FileDoc> files) {
		for(int i=0; i<files.size(); i++) {
			FileDoc doc = files.get(i);
			if (doc.getFile().equalsIgnoreCase(fileName)) {
				SysTool.deleteFile(Application.DIR_CORP_DOC.getDisk() + "/" + fileName);
				files.remove(i);
				break;
			}
		}
	}

	/**
	 * 删除企业附件资料
	 * 
	 * @param corpUid
	 * @param list
	 */
	public void deleteDoc(String corpUid, List<String> list) {
		SysCorpBean corp = dao.getCorp(corpUid, SysCorpBean.class);
		if (corp==null) 
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");

		List<FileDoc> files = StrTool.isBlank(corp.getDocs()) ? new ArrayList<>() : JsonTool.jsonToListBean(corp.getDocs(), FileDoc.class);
		for(String item: list) {
			deleteFile(item, files);
		}

		dao.updateCorpDoc(corp.getId(), files);
	}
	
	/**
	 * 查询企业信息
	 * @param req
	 * @return
	 */
	public Page<SysCorpVO> queryCorp(QueryCorpRequest req) {
		return dao.queryCorp(req);
	}

	//////////////////////////////////////////////// 静态接口 /////////////////////////////////////////////

	/**
	 * 获取企业详情
	 * @param corp
	 * @return
	 */
	public static SysCorpVO getCorp(String corpUid) {
		SysCorpDao dao = new SysCorpDao();
		return dao.getCorp(corpUid, SysCorpVO.class);
	}
	
	/**
	 * @param ctype 企业类型=>对应 dic_const.ctype 常量，传参若<1，表示忽略此参数
	 * @param corpName 企业名称
	 * @return
	 */
	public static SysCorpVO getCorpByName(int ctype, String corpName) {
		SysCorpDao dao = new SysCorpDao();
		return dao.getCorp(ctype, corpName, SysCorpVO.class);
	}

	/**
	 * @param ctype 企业类型=>对应 dic_const.ctype 常量，传参若<1，表示忽略此参数
	 * @param corpName 企业名称
	 * @return
	 */
	public static List<SysCorpVO> queryCorpByName(int ctype, String corpName) {
		SysCorpDao dao = new SysCorpDao();
		return dao.queryCorp(ctype, corpName);
	}
	
	/**
	 * 企业注册(用户注册时，同时注册企业信息)
	 * 
	 * @param ctype 企业类型
	 * @param corpName
	 * @param linkMan
	 * @param linkTel
	 * @return
	 */
	public static String registerCorp(int ctype, String corpName, String linkMan, String linkTel) {
		if (Application.userDelegate!=null) Application.userDelegate.beforeRegisterCorp(ctype, corpName);

		SysCorpDao dao = new SysCorpDao();
		String corpUid = dao.registerCorp(ctype, corpName, linkMan, linkTel);
		SysCorpVO newCorp = dao.getCorp(corpUid, SysCorpVO.class);
		if (Application.userDelegate!=null) Application.userDelegate.afterNewCorp(newCorp);
		return corpUid;
	}
	
	/**
	 * 管理员添加企业
	 * 
	 * @param corp
	 * @return
	 */
	public static void newCorp(CreateCorpRequest corp) {
		if (Application.userDelegate!=null) Application.userDelegate.beforeNewCorp(corp);
		
		SysCorpDao dao = new SysCorpDao();
		String corpUid = dao.newCorp(corp);
		SysCorpVO newCorp = dao.getCorp(corpUid, SysCorpVO.class);
		if (Application.userDelegate!=null) Application.userDelegate.afterNewCorp(newCorp);
	}
	
	/**
	 * 删除企业及企业附件
	 * 
	 * @param id
	 * @return
	 */
	public static SysCorpBean delCorp(long id) {
		SysCorpDao dao = new SysCorpDao();
		SysCorpBean corp = dao.getRecord(id, SysCorpVO.class);
		if (corp==null)
			throw new AppException(SysErr.SYS_DATA_NOT_FOUND, "无此企业信息.");

		if (corp.getCtype()==SysCorpBean.SUPPER_CORP)
			throw new AppException(SysErr.SYS_ACCESS_FORBID, "平台企业,不可删除.");

		List<FileDoc> files = JsonTool.jsonToListBean(corp.getDocs(), FileDoc.class);
		if (files!=null && files.size()>0) {
			for(FileDoc file: files) {
				SysTool.deleteFile(Application.DIR_CORP_DOC.getDisk() + "/" + file.getFile());
			}
		}

		dao.delRecord(id);
		return corp;		
	}
}
